
#include "spserver.h"
#include "fd.h"
#include "Session.h"
#include "SessionList.h"
#include "Acceptor.h"
#include "IoHandler.h"

#define MAX_EVENT_COUNT 64

void Acceptor::AcceptorRoutine(void* acceptor)
{
	Acceptor* pAcceptor = (Acceptor*)acceptor;
	IoHandler* pIoHandler = pAcceptor->ioHandler;
	int kq1 = pAcceptor->kq;

	struct kevent events[MAX_EVENT_COUNT];
	while(true) 
	{
		int ret = kevent(kq1, NULL, 0, events, MAX_EVENT_COUNT, NULL);

		for (int i = 0; i < ret; ++i)
		{

			for (int j = 0; j < events[i].data; ++j)
			{
				Session* pSession = pIoHandler->AllocAcceptSession();
				if (pSession)
				{
					pSession->SetSocket(accept(pAcceptor->acceptSocket, NULL, NULL));

					pIoHandler->GetAcceptedSessionList()->lock();
					pIoHandler->GetAcceptedSessionList()->push_back(pSession);
					pIoHandler->GetAcceptedSessionList()->unlock();
				}
				else
				{
					printf("max accept socket\n");
					break;
				}
			}
		}

	}
}

bool Acceptor::startListen(const char* szIp, int port)
{
	sockaddr_in sin;
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	sin.sin_addr.s_addr = (szIp == NULL) ? htonl(INADDR_ANY):inet_addr(szIp);

	acceptSocket = socket(sin.sin_family, SOCK_STREAM, 0);
	
	if (acceptSocket == retired_fd)
	{
		return false;
	}

	if (bind(acceptSocket,(struct sockaddr *)&sin, sizeof(sockaddr)) == -1)
	{
		return false;
	}

	if (listen(acceptSocket, 5) == -1)
	{
		return false;
	}
	
	struct kevent changes[1];
	EV_SET(&changes[0], acceptSocket, EVFILT_READ, EV_ADD, 0, 0, NULL);

	printf("kevent register %d\n",kevent(kq, changes, 1, NULL, 0, NULL)); 


	//worker.start(AcceptorRoutine, this);
	return true;
}

Acceptor::Acceptor()
{
	ioHandler = NULL;
	kq = 0;
	acceptSocket = retired_fd;

}

bool Acceptor::init(IoHandler* pIoHandler)
{
	kq = kqueue();
	ioHandler = pIoHandler;
	worker.start(AcceptorRoutine, this);
	return true;
}

